package com.app.biz.server;




import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.app.biz.domain.BizAppChatMsg;
import com.app.biz.service.IBizAppChatMsgService;
import com.app.common.utils.uuid.IdUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.OnError;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@ServerEndpoint("/chat/{userId}/{senderId}")
@Component

public class ChatMessageServer {

    protected final Logger log = LoggerFactory.getLogger(this.getClass());

    private static AtomicInteger onlineNum = new AtomicInteger(0);
    private static Map<String, Session> sessionPools = new ConcurrentHashMap<>();


    private static IBizAppChatMsgService bizAppChatMsgService;

    @Autowired
    public void setMsgInboxService(IBizAppChatMsgService bizAppChatMsgService) {
        ChatMessageServer.bizAppChatMsgService = bizAppChatMsgService;
    }




    public void sendMessage(Session session, String message) throws IOException {
        if (session != null) {
            synchronized (session) {
                log.info("发送数据：" + message);
                session.getBasicRemote().sendText(message);
            }
        }
    }

    public void sendInfo(String userId, String message) {
        Session session = sessionPools.get(userId);
        try {
            sendMessage(session, message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void broadcast(String message) {
        sessionPools.values().forEach(session -> {
            try {
                sendMessage(session, message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }

    @OnOpen
    public void onOpen(Session session, @PathParam(value = "userId") String userId, @PathParam(value = "senderId") String senderId) {
        sessionPools.put(userId, session);
        onlineNum.incrementAndGet();
        log.info(userId + " 加入 WebSocket！当前人数为 " + onlineNum);
        if("-1".equals(senderId)){//代表提问
            // 加载历史消息
            loadDealerHistoryMessages(userId);
        }else{//代表回复
            // 加载历史消息
            loadHistoryMessages(senderId);
        }


    }

    @OnClose
    public void onClose(@PathParam(value = "userId") String userId) {
        sessionPools.remove(userId);
        onlineNum.decrementAndGet();
        log.info(userId + " 断开 WebSocket 连接！当前人数为 " + onlineNum);

    }

    @OnMessage
    public void onMessage(String message) throws IOException {
        log.info("server get " + message);
        BizAppChatMsg msg = JSON.parseObject(message, BizAppChatMsg.class);
        msg.setBaseId(IdUtils.fastUUID());
        //msg.setReceiverId("1");
        msg.setCreateTime(new Date());
        msg.setUpdateTime(new Date());
        msg.setCreateBy(msg.getSenderId());
        msg.setUpdateBy(msg.getSenderId());
        //保存消息到数据库
        bizAppChatMsgService.insertBizAppChatMsg(msg);
        String receiverId = msg.getReceiverId() != null ? msg.getReceiverId() : "-1";
        sendInfo(receiverId, JSONObject.toJSONString(msg));
    }

    @OnError
    public void onError(Session session, Throwable throwable) throws IOException {
        log.info("发生错误");
        throwable.printStackTrace();
    }

    private void loadHistoryMessages(String userId) {
        BizAppChatMsg bizAppChatMsg = new BizAppChatMsg();
        bizAppChatMsg.setReceiverId(userId);
        List<BizAppChatMsg> messages = bizAppChatMsgService.selectHistoryBizAppChatMsgList(bizAppChatMsg);
        messages.forEach(msg -> {
            try {
                sendMessage(sessionPools.get(userId), JSONObject.toJSONString(msg));
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }


    private void loadDealerHistoryMessages(String userId) {
        BizAppChatMsg bizAppChatMsg = new BizAppChatMsg();
        bizAppChatMsg.setReceiverId(userId);
        List<BizAppChatMsg> messages = bizAppChatMsgService.selectHistoryBizAppChatMsgList(bizAppChatMsg);
        messages.forEach(msg -> {
            try {
                sendMessage(sessionPools.get(userId), JSONObject.toJSONString(msg));
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }


    public void saveAndSendMessage(String message) throws IOException {
        log.info("server get " + message);
        BizAppChatMsg msg = JSON.parseObject(message, BizAppChatMsg.class);
        msg.setCreateTime(new Date());
        msg.setUpdateTime(new Date());
        msg.setCreateBy(msg.getSenderId());
        msg.setUpdateBy(msg.getSenderId());
        //保存消息到数据库
        bizAppChatMsgService.insertBizAppChatMsg(msg);

        sendInfo(msg.getReceiverId(), JSONObject.toJSONString(msg));
    }

    public static AtomicInteger getOnlineNumber() {
        return onlineNum;
    }

    public static Map<String, Session> getSessionPools() {
        return sessionPools;
    }
}
